import pandas as pd
import numpy as np
import datetime
import base64
from elasticsearch import Elasticsearch
from es_config import ES_IP, get_now_date
es = Elasticsearch(ES_IP)
instance_df_head = ['service_instance_cpm', 'service_instance_sla',
                    'service_instance_resp_time', 'instance_jvm_cpu', 'instance_jvm_memory_heap',
                    'instance_jvm_memory_noheap']

print(es)

def time_transform(time_bucket, minutes):
    time_bucket = str(time_bucket)
    index = False
    if len(time_bucket) == 12:
        index = int(time_bucket[8:10]) * 60 + int(time_bucket[10:])
        index = index - minutes
    return index


def get_service_attr(source, instance_dict, index, date, tag):    #处理一个source
    minutes = date.hour * 60 + date.minute
    instance_id = source['entity_id']
    time_bucket = time_transform(source['time_bucket'], minutes)
    if instance_df_head[index] == 'service_instance_sla':
        value = source['percentage'] / 100
    elif instance_df_head[index] == 'instance_jvm_memory_heap' or \
             instance_df_head[index] == 'instance_jvm_memory_noheap':
        value = source['value'] / 2**20
    else:
        value = source['value']
    if tag == 'start':
        rows = 24 * 60 - minutes
    elif tag == 'end':
        rows = minutes
    elif tag == 'full':
        rows = 24 * 60
    else:
        tag = tag.hour * 60 + tag.minute
        rows = tag - minutes
    if not time_bucket:
        return instance_dict, rows

    if instance_id not in instance_dict:
        instance_dict[instance_id] = np.zeros([rows, (1+len(instance_df_head))], float)
        instance_dict[instance_id][:, 0] = range(rows)
    if tag == 'end':
        instance_dict[instance_id][time_bucket][1 + index] = value
    else:
        instance_dict[instance_id][time_bucket-1][1 + index] = value
    return instance_dict, rows


def instance_utils(instance_dict, rows):
    for instance in instance_dict:      #对每一个instance_id
        for index in range(len(instance_df_head)):
            for i in range(1, rows):
                if instance_dict[instance][i, (1+index)] == 0:
                    instance_dict[instance][i, (1+index)] = instance_dict[instance][(i-1), (1+index)]
        instance_dict[instance] = pd.DataFrame(instance_dict[instance])
        instance_dict[instance].columns = ['time', 'service_instance_cpm', 'service_instance_sla',
                    'service_instance_resp_time', 'instance_jvm_cpu', 'instance_jvm_memory_heap',
                    'instance_jvm_memory_noheap']
        idlist = instance.split('_')
        try:
            service_id = str(base64.b64decode(idlist[0].encode('utf-8')), encoding='utf-8')

        except:
            service_id = str(base64.b64decode(idlist[0][:-2].encode('utf-8')), encoding='utf-8')
        try:
            instance_id = str(base64.b64decode(idlist[1].encode('utf-8')), encoding='utf-8')
        except:
            instance_id = str(base64.b64decode(idlist[1][:-2].encode('utf-8')), encoding='utf-8')
        instance_dict[instance].insert(1, 'service_id', [service_id]*rows)
        instance_dict[instance].insert(2, 'instance_id', [instance_id] * rows)
        instance_dict[instance].set_index(keys='time', inplace=True)
    return instance_dict


def choice_body(date, tag):
    date = date.strftime("%Y%m%d%H%M")
    if tag == 'full':
        body = {
            'query': {
                'match_all': {}
            }
        }
    elif tag == 'start':
        body = {
            'query': {
                'range': {
                    'time_bucket':
                        {
                            'gt': date
                        }
                }
            }
        }
    elif tag == 'end':
        body = {
            'query': {
                'range': {
                    'time_bucket':
                        {
                            'lte': date
                        }
                }
            }
        }
    else:
        tag = tag.strftime("%Y%m%d%H%M")
        body = {
            'query': {
                'range': {
                    'time_bucket':
                        {
                            'gt': date,
                            'lte': tag
                        }
                }
            }
        }
    return body


def get_instance_data(instance_dict, index, date, tag):
    d = date.strftime("%Y%m%d")
    file_name = instance_df_head[index] + '-' + str(d)
    body = choice_body(date, tag)
    print(file_name, body)
    print("====")
    allDoc = es.search(index=file_name, body=body, scroll='5m', size=100)
    results = allDoc['hits']['hits']  # 第一页
    total = allDoc['hits']['total']['value']
    scroll_id = allDoc['_scroll_id']
    for i in range(0, int(total / 100) + 1):
        query_scroll = es.scroll(scroll_id=scroll_id, scroll='5m')['hits']['hits']
        results += query_scroll    #结果全部加载到内存
    for result in results:
        instance_dict, rows = get_service_attr(result['_source'], instance_dict, index, date, tag)
    return instance_dict, rows


def get_instance_dict(date, tag='full'):
    instance_dict = {}
    for index in range(len(instance_df_head)):
        instance_dict, rows = get_instance_data(instance_dict, index, date, tag)
    instance_dict = instance_utils(instance_dict, rows)
    return instance_dict


def not_today(days, start_time, now_time):
    dict_list = []
    dls = get_instance_dict(start_time, 'start')
    keys = set(dls.keys())
    dict_list.append(dls)
    for day in range(days - 1):
        date = start_time + datetime.timedelta(days=day)
        dl = get_instance_dict(date)
        dict_list.append(dl)
        keys.union(set(dl.keys()))
    dle = get_instance_dict(now_time, 'end')
    dict_list.append(dle)
    keys.union(set(dle.keys()))
    total_df = pd.DataFrame([])
    for i in iter(keys):
        df = pd.DataFrame([])
        for d in dict_list:
            if i in d.keys():
                df = pd.concat([df, d[i]], ignore_index=True)
        total_df = pd.concat([total_df, df], ignore_index=False)
    # total_df.to_csv('./instance_24h.csv', header=True, index=True)
    return total_df


def today(start_time, now_time):
    d = get_instance_dict(start_time, now_time)
    keys = set(d.keys())
    df = pd.DataFrame([])
    for i in iter(keys):
        df = pd.concat([df, d[i]], ignore_index=False)
    # df.to_csv('./instance_today.csv', header=True, index=True)
    return df


def get_instances(ahead_hour, time1):
    # now_time = datetime.datetime.now() + datetime.timedelta(hours=8)  # 现在的时间
    now_time = time1
    # now_date = now_time.strftime("%Y%m%d")  # 获取日期：年、月、日
    # now_minutes = now_time.hour * 60 + now_time.minute  # 当前日期的时间:时*60+分

    start_time = now_time - datetime.timedelta(hours=ahead_hour)  # 开始时间
    # start_date = start_time.strftime("%Y%m%d")  # 开始记录的日期：年、月、日
    # start_minutes = start_time.hour * 60 + now_time.minute  # 开始记录的时间:时*60+分

    # total_minutes = (now_time - start_time).total_seconds() // 60  # 总时间（最后得到的分钟数）
    days = (now_time-start_time).days
    if days == 0:
        df = today(start_time, now_time)
    else:
        df = not_today(days, start_time, now_time)
    return df




if __name__ == '__main__':
    print(ES_IP)
    df = get_instances(1)
    print(df)

